# 类/方法：TableManager
from typing import Dict, List, Optional, Union, Any
from .table import Table
from .booter import Booter
# from storage.data_manager import DataManager
# from utils.parser import Parser
from src.storage.data_manager import DataManager
from src.utils.parser import Parser
# 注意：去除对执行层的模块级导入，避免循环依赖
class TableManager:
    """
    表管理器
    """

    def __init__(self,  data_manager: DataManager ,booter: Booter):
        """初始化表管理器
    
        支持两种参数顺序：
        - (path: str, data_manager: DataManager)
        - (data_manager: DataManager, path: str)
        """

        self.data_manager = data_manager
        self.booter = booter
        # 名表缓存
        self.table_cache: Dict[str, Table] = {}
        # Transaction ID表缓存
        self.xid_table_cache: Dict[int, List[Table]] = {}
        # 可选：供Field创建内存索引使用
        self.buffer_pool_manager = getattr(self.data_manager, "buffer_pool", None) or getattr(self.data_manager, "buffer_pool_manager", None)
        
        # 加载已有表
        self._load_tables()


    '''
    table链表
    '''
    def _first_table_uid(self) -> int:
        """获取第一个表的UID"""
        raw = self.booter.load()
        return Parser.parse_long(raw) if raw else 0

    def _update_first_table_uid(self, uid: int) -> None:
        """更新第一个表的UID"""
        raw = Parser.long_to_bytes(uid)
        self.booter.update(raw)

    def _load_tables(self) -> None:
        """加载所有表"""
        uid = self._first_table_uid()
        while uid != 0:
            table = Table.load_table(self, uid)
            uid = table.next_uid
            self.table_cache[table.name] = table

    '''
    操作
    '''
    def show(self, xid: int) -> bytes:
        """显示所有表"""
        result = []
        for table in self.table_cache.values():
            result.append(str(table))
        
        # 添加事务中创建的表
        if xid in self.xid_table_cache:
            for table in self.xid_table_cache[xid]:
                result.append(str(table))
        
        return '\n'.join(result).encode('utf-8')
    
    def create_table(self, xid: int, statement:Any) -> bytes:
        """创建表
        
        Args:
            xid: 事务ID
            table_name: 表名
            field_names: 字段名列表
            field_types: 字段类型列表
            indexes: 索引字段列表
            
        Returns:
            操作结果
            :param xid:
            :param statement:
        """
        table_name = statement.table_name
        field_names = statement.field_names
        field_types = statement.field_types
        indexes= getattr(statement, 'indexes', None)

        if table_name in self.table_cache:
            raise Exception(f"Table {table_name} already exists")
        
        # 获取下一个表的UID（当前为0，表示这是最后一个表）
        next_uid = 0

        # 创建表
        table = Table.create_table(self, next_uid, xid, table_name, 
                                 field_names, field_types, indexes or [])
        
        # 更新第一个表的UID
        if not self.table_cache:  # 如果这是第一个表
            self._update_first_table_uid(table.uid)
        else:
            # 将新表插入到链表头部
            old_first_uid = self._first_table_uid()
            table.next_uid = old_first_uid
            table.persist_self(xid)  # 重新持久化
            self._update_first_table_uid(table.uid)

        # 添加到缓存
        self.table_cache[table_name] = table
        
        return b'create'

    def insert(self, xid: int, statement: Any) -> bytes:
        """直接执行INSERT操作"""
        table_name = statement.table_name
        values = getattr(statement, 'values', None)
        values_list = getattr(statement, 'values_list', None)

        if table_name not in self.table_cache:
            raise Exception(f"Table {table_name} not found")

        table = self.table_cache[table_name]

        # 优先处理 values_list（测试批量插入时传 values=None, values_list=[...]）
        if values_list is not None:
            if not isinstance(values_list, list):
                raise ValueError("values_list must be a list of records")
            inserted_count = 0
            for record in values_list:
                table.insert(xid, record)
                inserted_count += 1
            return f"Inserted {inserted_count} rows".encode('utf-8')

        # 处理 values 为空的情况
        if values is None:
            raise ValueError("INSERT statement missing values")

        # 处理单条或多条插入
        if isinstance(values, list) and len(values) > 0 and isinstance(values[0], list):
            # 多条插入：values 是二维列表
            inserted_count = 0
            for value_list in values:
                table.insert(xid, value_list)
                inserted_count += 1
            return f"Inserted {inserted_count} rows".encode('utf-8')
        else:
            # 单条插入
            table.insert(xid, values)
            return b'insert'

    def update(self, xid: int, statement: Any) -> bytes:
        """直接执行UPDATE操作"""
        table_name = statement.table_name
        set_values = statement.set_values
        where_conditions = getattr(statement, 'where_conditions', None)

        if table_name not in self.table_cache:
            raise Exception(f"Table {table_name} not found")

        table = self.table_cache[table_name]
        count = table.update(xid, set_values, where_conditions)

        return f"Updated {count} rows".encode('utf-8')

    def delete(self, xid: int, statement: Any) -> bytes:
        """直接执行DELETE操作"""
        table_name = statement.table_name
        where_conditions = getattr(statement, 'where_conditions', None)

        if table_name not in self.table_cache:
            raise Exception(f"Table {table_name} not found")

        table = self.table_cache[table_name]

        # 如果没有WHERE条件，删除所有记录
        if where_conditions is None:
            count = table.delete_all(xid)
        else:
            count = table.delete(xid, where_conditions)

        return f"Deleted {count} rows".encode('utf-8')

    '''
    复杂查询
    '''
    def select(self, xid: int, statement: Any) -> bytes:
        """处理复杂查询，委托给execution模块"""
        # 导入查询执行器
        from src.execution.query_executor import QueryExecutor
        from src.execution.executor import ExecutionContext, Schema

        # 创建执行上下文
        context = ExecutionContext(self)
        context.transaction_id = xid

        # 创建查询执行器
        query_executor = QueryExecutor(context)

        # 构建查询计划并执行
        from src.execution.query_executor import QueryPlan

        table_name = statement.table_name
        fields = getattr(statement, 'fields', None)
        where_conditions = getattr(statement, 'where_conditions', None)

        # 获取表结构
        schema_info = self.get_table_schema(table_name)

        from src.execution.executor import Schema
        schema = Schema(schema_info)

        # 构建扫描计划
        scan_plan = QueryPlan("seq_scan", table_name=table_name, schema=schema)

        current_plan = scan_plan

        # 添加过滤条件
        # *** 核心修复：如果存在WHERE条件，则添加Filter节点 ***
        if where_conditions:
            # 直接将 planner 生成的 conditions 字典传给 plan
            filter_plan = QueryPlan("filter", predicate=where_conditions, schema=schema)
            filter_plan.add_child(current_plan)
            current_plan = filter_plan


        # 添加投影
        if fields and fields != ['*']:
            projected_schema_info = [si for si in schema_info if si[0] in fields]
            projected_schema = Schema(projected_schema_info)
            projection_plan = QueryPlan("projection", fields=fields, schema=projected_schema)
            projection_plan.add_child(current_plan)
            current_plan = projection_plan

        results = query_executor.execute(current_plan)

        # 格式化结果
        if not results:
            return b''

        return results

    '''
    表相关
    '''
    def get_table(self, table_name: str):
        """获取表对象；不存在则抛出异常"""
        if table_name not in self.table_cache:
            raise Exception(f"Table {table_name} not found")
        return self.table_cache[table_name]
    def get_table_schema(self, table_name: str) -> List[tuple]:
        """提供执行引擎/服务端使用的简易Schema"""
        tb = self.get_table(table_name)
        if not tb:
            return []
        schema = []
        for f in tb.fields:
            t = f.field_type.value if isinstance(f.field_type, (str,)) is False else f.field_type
            # 将 FieldType 映射为执行器期望的字符串
            if isinstance(f.field_type, str):
                tname = f.field_type
            else:
                if f.field_type == f.field_type.INTEGER:
                    tname = "int"
                elif f.field_type == f.field_type.FLOAT:
                    tname = "float"
                elif f.field_type == f.field_type.BOOLEAN:
                    tname = "bool"
                else:
                    tname = "string"
            schema.append((f.name, tname))
        return schema

    '''
        关闭
    '''
    def close(self) -> None:
        """关闭表管理器"""
        self.booter.close()

    '''
     事务相关
     '''

    def begin(self, repeatable_read: bool = False) -> Dict[str, any]:
        """开始事务"""
        # 这里需要集成版本管理器
        # 暂时返回简单结果
        return {
            'xid': 1,  # 临时事务ID
            'result': b'begin'
        }

    def commit(self, xid: int) -> bytes:
        """提交事务"""
        # 集成版本管理器后实现
        return b'commit'

    def abort(self, xid: int) -> bytes:
        """回滚事务"""
        # 集成版本管理器后实现
        return b'abort'